package cn.kent.high.threadSync;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 回环屏障
 *
 *      private int dowait(boolean timed, long nanos)
 *         throws InterruptedException, BrokenBarrierException,
 *                TimeoutException {
 *         final ReentrantLock lock = this.lock;
 *         lock.lock();
 *         try {
 *             final Generation g = generation;
 *
 *             if (g.broken)
 *                 throw new BrokenBarrierException();
 *
 *             if (Thread.interrupted()) {
 *                 breakBarrier();
 *                 throw new InterruptedException();
 *             }
 *             // index == 0 表示到了屏障点，此时执行初始化的时传递的任务
 *             int index = --count;
 *             if (index == 0) {  // tripped
 *                 boolean ranAction = false;
 *                 try {
 *                     final Runnable command = barrierCommand;
 *                     if (command != null) // 执行任务
 *                         command.run();
 *                     ranAction = true;
 *                     nextGeneration(); // 激活其他因调用await方法而被阻塞的线程，并重置cyclicBarrier
 *                     return 0;
 *                 } finally {
 *                     if (!ranAction)
 *                         breakBarrier();
 *                 }
 *             }
 *
 *             // loop until tripped, broken, interrupted, or timed out
 *             for (;;) {
 *                 try {
 *                     if (!timed) // 没有设置超时时间
 *                         trip.await();
 *                     else if (nanos > 0L) // 设置了超时时间
 *                         nanos = trip.awaitNanos(nanos);
 *                 } catch (InterruptedException ie) {
 *                     if (g == generation && ! g.broken) {
 *                         breakBarrier();
 *                         throw ie;
 *                     } else {
 *                         // We're about to finish waiting even if we had not
 *                         // been interrupted, so this interrupt is deemed to
 *                         // "belong" to subsequent execution.
 *                         Thread.currentThread().interrupt();
 *                     }
 *                 }
 *
 *                 if (g.broken)
 *                     throw new BrokenBarrierException();
 *
 *                 if (g != generation)
 *                     return index;
 *
 *                 if (timed && nanos <= 0L) {
 *                     breakBarrier();
 *                     throw new TimeoutException();
 *                 }
 *             }
 *         } finally {
 *             lock.unlock();
 *         }
 *     }
 */
public class CycleBarrierTest2 {
    // 创建实例
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread() + " step1");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + " step2");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + " step3");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread() + " step1");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + " step2");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + " step3");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        // 关闭线程池
        executorService.shutdown();

    }

}
